package ntu.sna;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections15.Factory;
import org.apache.commons.collections15.Transformer;
import org.apache.commons.collections15.map.HashedMap;

import edu.uci.ics.jung.algorithms.cluster.WeakComponentClusterer;
import edu.uci.ics.jung.algorithms.filters.FilterUtils;
import edu.uci.ics.jung.algorithms.shortestpath.DijkstraShortestPath;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.SparseMultigraph;
import edu.uci.ics.jung.graph.UndirectedSparseGraph;
import edu.uci.ics.jung.graph.util.EdgeType;

public class BasicDirectedGraph {
    public static int edgeCount= 0;
	
	public static void main(String[] args) {
		Graph< MyNode , MyLink> g = new SparseMultigraph<MyNode,MyLink>();
		MyNode n1 = new MyNode(1);
		MyNode n2 = new MyNode(2);
		MyNode n3 = new MyNode(3);
		MyNode n4 = new MyNode(4);
		MyNode n5 = new MyNode(5);
		
		g.addEdge(new MyLink(2.0 , 48) , n1, n2,EdgeType.DIRECTED);
		g.addEdge(new MyLink(2.0 , 48) , n2, n3,EdgeType.DIRECTED);
		g.addEdge(new MyLink(3.0 , 192) , n3, n5,EdgeType.DIRECTED);
		g.addEdge(new MyLink(2.0 , 48) , n5, n4,EdgeType.DIRECTED);
		g.addEdge(new MyLink(2.0 , 48) , n4, n2,EdgeType.DIRECTED);
		g.addEdge(new MyLink(2.0 , 48) , n3, n1,EdgeType.DIRECTED);
		g.addEdge(new MyLink(10.0 , 48) , n2, n5,EdgeType.DIRECTED);
		
		System.out.println(g);

		DijkstraShortestPath<MyNode , MyLink> alg = new DijkstraShortestPath<MyNode , MyLink>(g);
		List<MyLink> l = alg.getPath(n1, n4 );
		System.out.println(l);		
		
		Transformer<MyLink , Double> wtTransformer = new Transformer<MyLink , Double>(){
			public Double transform(MyLink link){
				return link.weight;
			}
		};
		
		DijkstraShortestPath<MyNode , MyLink> alg2 = new DijkstraShortestPath<MyNode , MyLink>(g,wtTransformer);
		List<MyLink> l2 = alg2.getPath(n1, n4 );
		Number dist = alg2.getDistance(n1, n4);
		System.out.println(l2);
		
		Transformer<MyLink , Double> capTransformer = new Transformer<MyLink , Double>(){
			public Double transform(MyLink link){
				return link.capacity;
			}
		};
		Map<MyLink , Double> edgeFlowMap = new HashedMap<MyLink, Double>();
		
		Factory<MyLink> edgeFactory = new Factory<MyLink>(){
			public MyLink create(){
				return new MyLink(1.0 , 1.0);
			}
		};
		/*
		EdmondsKarpMaxFlow<MyNode, MyLink> alg3 ;
				new EdmondsKarpMaxFlow<MyNode, MyLink>(g,n2, n5, capTransformer, edgeFlowMap , edgeFactory);
		*/
		
		Graph< MyNode , MyLink> g4 = new UndirectedSparseGraph<MyNode,MyLink>();
		MyNode n6 = new MyNode(6);
		MyNode n7 = new MyNode(7);
		MyNode n8 = new MyNode(8);
		MyNode n9 = new MyNode(9);
		MyNode n10 = new MyNode(10);
		MyNode n11 = new MyNode(11);
		MyNode n12 = new MyNode(12);
		
		g4.addEdge(new MyLink(2.0 , 48) , n6, n7);
		g4.addEdge(new MyLink(2.0 , 48) , n7, n8);
		g4.addEdge(new MyLink(3.0 , 192) , n8, n9);
		g4.addEdge(new MyLink(2.0 , 48) , n9, n7);
		g4.addEdge(new MyLink(2.0 , 48) , n9, n6);		
		g4.addEdge(new MyLink(2.0 , 48) , n6, n8);	
		g4.addEdge(new MyLink(2.0 , 48) , n6, n10);
		g4.addEdge(new MyLink(2.0 , 48) , n11, n10);
		g4.addEdge(new MyLink(2.0 , 48) , n12, n11);
		
        AssortativityCalculator<MyNode , MyLink> ac = 
        	new AssortativityCalculator<MyNode , MyLink>(g4);
        double tmp = ac.run();
        System.out.println("Assortativity:"+tmp);
        
        
        // GCC 
        Graph< MyNode , MyLink> g5 = new SparseMultigraph<MyNode,MyLink>();
		MyNode n13 = new MyNode(13);
		MyNode n14 = new MyNode(14);
		MyNode n15 = new MyNode(15);
		MyNode n16 = new MyNode(16);
		MyNode n17 = new MyNode(17);
		
		g5.addEdge(new MyLink(2.0 , 48) , n13, n14);
		g5.addEdge(new MyLink(2.0 , 48) , n14, n15);
		g5.addVertex(n16);
		g5.addVertex(n17);
		
		GiantConnectedComponentCalculator< MyNode , MyLink> gccc =
			new GiantConnectedComponentCalculator< MyNode , MyLink>(g5);
        
		double  i = gccc.run();
		System.out.println("gcc_rate:"+i);
        
        
		
	}

}
/*
class MyNode {
	static int vertexCount = 0;
	int id;
	public MyNode(){
		this.id =vertexCount++;
	}
	public MyNode(int id){
		this.id =id;
	}
	public String toString(){
	    return "V"+id;
	}
	
}

class MyLink {
	static int edgeCount = 0;
	double capacity;
	double weight;
	int id;
	public MyLink(double weight, double capacity){
		this.id = edgeCount++;
		this.weight = weight;
		this.capacity = capacity;
		
	}
	
	public String toString(){
	    return "E"+id;
	}
}*/